//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package org.tuiofx.internal.gesture;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import javafx.application.Platform;
import javafx.event.Event;
import javafx.event.EventTarget;
import javafx.event.EventType;
import javafx.geometry.Point2D;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.input.ContextMenuEvent;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseDragEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.PickResult;
import javafx.scene.input.ScrollEvent;
import javafx.scene.input.TouchEvent;
import javafx.scene.input.TouchPoint;
import javafx.scene.input.ScrollEvent.HorizontalTextScrollUnits;
import javafx.scene.input.ScrollEvent.VerticalTextScrollUnits;
import javafx.stage.Stage;
import org.tuiofx.Configuration;
import org.tuiofx.internal.base.TargetSelection;
import org.tuiofx.internal.gesture.TuioTouchPoint.State;
import org.tuiofx.internal.util.LogUtils;

public abstract class GestureRecognizer {
    protected final Configuration config;
    protected Stage stage;
    protected Scene scene;
    private Node targetNode;
    protected HashMap<Integer, TuioTouchPoint> touchPointsMap;
    protected Vector<TuioTouchPoint> touchPointsList;
    protected int touchPointsCount = 0;
    protected int requiredNumberOfTouches = 0;
    protected int maxNumberOfTouches = 5;
    private GestureState state;
    public static final double TOUCH_SLOP = 10.0;
    private TargetSelection targetSelection;

    public GestureRecognizer(Node targetNode, Configuration config) {
        this.targetNode = targetNode;
        this.touchPointsMap = new HashMap<>();
        this.touchPointsList = new Vector();
        this.config = config;
    }

    public void setRequiredNumberOfTouches(int number) {
        this.requiredNumberOfTouches = number;
    }

    public void preTouchesBegan(TuioTouchPoint touchPoint) {
        this.touchPointsMap.put(touchPoint.getSessionID(), touchPoint);
        this.touchPointsList.add(touchPoint);
        ++this.touchPointsCount;
        this.touchesBegan(touchPoint);
    }

    public void preTouchesMove(TuioTouchPoint touchPoint) {
        if (this.touchPointsMap.replace(touchPoint.getSessionID(), touchPoint) == null) {
            LogUtils.error("touchPoint in touchPointsMap is missing");
        }

        int index = this.touchPointsList.indexOf(touchPoint);
        if (index > -1) {
            this.touchPointsList.set(index, touchPoint);
        } else {
            LogUtils.error("touchPoint in touchPointsList is missing");
        }

        this.touchesMove(touchPoint);
    }

    public void preTouchesEnd(TuioTouchPoint touchPoint) {
        --this.touchPointsCount;
        if (this.touchPointsMap.remove(touchPoint.getSessionID()) == null) {
            LogUtils.error("Couldn't remove touchPoint in touchPointsMap size = " + this.touchPointsMap.size());
        }

        if (!this.touchPointsList.remove(touchPoint)) {
            LogUtils.error("Couldn't remove touchPoint in touchPointsList");
        }

        this.touchesEnd(touchPoint);
    }

    public EventTarget getEventTarget() {
        return this.targetNode;
    }

    public Node getTargetNode() {
        return this.targetNode;
    }

    protected void fireEvent(EventTarget eventTarget, Event event) {
        Event.fireEvent(eventTarget, event);
    }

    protected void fireContextEventMenu(final TuioTouchPoint touchPoint) {
        Platform.runLater(new Runnable() {
            public void run() {
                EventTarget eventTarget = touchPoint.getTargetNode();
                boolean isKeyboardTrigger = false;
                PickResult pickResult = new PickResult(eventTarget, touchPoint.getSceneX(), touchPoint.getSceneY());
                ContextMenuEvent context = new ContextMenuEvent(ContextMenuEvent.CONTEXT_MENU_REQUESTED, touchPoint.getSceneX(), touchPoint.getSceneY(), touchPoint.getScreenX(), touchPoint.getScreenY(), isKeyboardTrigger, pickResult);
                GestureRecognizer.this.fireEvent(eventTarget, context);
            }
        });
    }

    protected void fireTouchEvent(TuioTouchPoint touchPoint, TouchPoint.State state) {
        EventTarget eventTarget = touchPoint.getTargetNode();
        if (eventTarget == null) {
            LogUtils.warn("EventTarget should not be null!");
        }

        double x = touchPoint.getSceneX();
        double y = touchPoint.getSceneY();
        Platform.runLater(() -> {
            List<TouchPoint> touchList = new ArrayList<>();
            Iterator var9 = this.touchPointsList.iterator();

            while (var9.hasNext()) {
                TuioTouchPoint tPts = (TuioTouchPoint) var9.next();
                TouchPoint.State touchState = null;
                if (tPts.getState() == State.STARTED) {
                    touchState = javafx.scene.input.TouchPoint.State.PRESSED;
                } else if (tPts.getState() == State.MOVED) {
                    double deltaX = tPts.getSceneX() - tPts.getLastSceneX();
                    double deltaY = tPts.getSceneY() - tPts.getLastSceneY();
                    if (!(Math.abs(deltaX) > TOUCH_SLOP) && !(Math.abs(deltaY) > TOUCH_SLOP)) {
                        touchState = javafx.scene.input.TouchPoint.State.STATIONARY;
                    } else {
                        touchState = javafx.scene.input.TouchPoint.State.MOVED;
                    }
                } else if (tPts.getState() == State.ENDED) {
                    touchState = javafx.scene.input.TouchPoint.State.RELEASED;
                }

                if (touchState == null) {
                    LogUtils.error("touchState should not be null.");
                }

                PickResult pickResult = new PickResult(eventTarget, tPts.getSceneX(), tPts.getSceneY());
                TouchPoint fxTouchPoint = new TouchPoint(tPts.getId(), touchState, tPts.getSceneX(), tPts.getSceneY(), tPts.getScreenX(), tPts.getScreenY(), eventTarget, pickResult);
                touchList.add(fxTouchPoint);
            }

            Integer touchEventSetId = touchPoint.getSessionID();
            EventType<TouchEvent> touchType = null;
            if (state == javafx.scene.input.TouchPoint.State.PRESSED) {
                touchType = TouchEvent.TOUCH_PRESSED;
            } else if (state == javafx.scene.input.TouchPoint.State.MOVED) {
                touchType = TouchEvent.TOUCH_MOVED;
            } else if (state == javafx.scene.input.TouchPoint.State.RELEASED) {
                touchType = TouchEvent.TOUCH_RELEASED;
            } else if (state == javafx.scene.input.TouchPoint.State.MOVED) {
                touchType = TouchEvent.TOUCH_MOVED;
            } else if (state == javafx.scene.input.TouchPoint.State.STATIONARY) {
                touchType = TouchEvent.TOUCH_STATIONARY;
            }

            if (touchType == null) {
                LogUtils.error("Could not fire TouchEvent. TouchType should not be null!");
            } else {
                PickResult pRes = new PickResult(eventTarget, x, y);
                TouchPoint tp = new TouchPoint(touchPoint.getId(), state, x, y, touchPoint.getScreenX(), touchPoint.getScreenY(), eventTarget, pRes);
                this.fireEvent(eventTarget, new TouchEvent(touchType, tp, touchList, touchEventSetId, false, false, false, false));
            }
        });
    }

    protected void fireScrollEvent(final TuioTouchPoint touchPoint, final EventType<ScrollEvent> eventType, final double x, final double y, final double screenX, final double screenY, final double deltaX, final double deltaY, final double totalDeltaX, final double totalDeltaY, final boolean inertia) {
        final ScrollEvent.HorizontalTextScrollUnits textDeltaXUnits = HorizontalTextScrollUnits.NONE;
        final ScrollEvent.VerticalTextScrollUnits textDeltaYUnits = VerticalTextScrollUnits.NONE;
        final double textDeltaX = 0.0;
        final double textDeltaY = 0.0;
        final int touchCount = this.touchPointsCount;
        final boolean direct = true;
        Platform.runLater(new Runnable() {
            public void run() {
                PickResult pickResult = new PickResult(GestureRecognizer.this.targetNode, x, y);
                GestureRecognizer.this.fireEvent(touchPoint.getTargetNode(), new ScrollEvent(eventType, x, y, screenX, screenY, false, false, false, false, direct, inertia, deltaX, deltaY, totalDeltaX, totalDeltaY, textDeltaXUnits, textDeltaX, textDeltaYUnits, textDeltaY, touchCount, pickResult));
            }
        });
    }

    protected void fireScrollEvent(TuioTouchPoint touchPoint, EventType<ScrollEvent> eventType, double deltaX, double deltaY, double totalDeltaX, double totalDeltaY) {
        double centroidX = this.getCentroid().getX();
        double centroidY = this.getCentroid().getY();
        double x;
        double y;
        double screenX;
        double screenY;
        if (!Double.isNaN(centroidX) && !Double.isNaN(centroidY)) {
            x = centroidX;
            y = centroidY;
            Point2D screenXY = this.sceneXYToscreenYX(centroidX, centroidY);
            screenX = screenXY.getX();
            screenY = screenXY.getY();
        } else {
            x = touchPoint.getSceneX();
            y = touchPoint.getSceneY();
            screenX = touchPoint.getScreenX();
            screenY = touchPoint.getScreenY();
        }

        this.fireScrollEvent(touchPoint, eventType, x, y, screenX, screenY, deltaX, deltaY, totalDeltaX, totalDeltaY, false);
    }

    protected void fireMouseDragEvent(TuioTouchPoint touchPoint, EventType<MouseDragEvent> eventType, boolean primaryButtonDown, boolean secondaryButtonDown, int clickCount, MouseButton button, Object gestureSource) {
        boolean synthesized = true;
        boolean shiftDown = false;
        boolean controlDown = false;
        boolean middleButtonDown = false;
        boolean metaDown = false;
        boolean popupTrigger = false;
        boolean altDown = false;
        double sceneX = touchPoint.getSceneX();
        double sceneY = touchPoint.getSceneY();
        double screenX = touchPoint.getScreenX();
        double screenY = touchPoint.getScreenY();
        Platform.runLater(() -> {
            PickResult pickResult = new PickResult(touchPoint.getCurrentTargetNode(), touchPoint.getSceneX(), touchPoint.getSceneY());
            MouseEvent mouseDragEvent = new MouseDragEvent(eventType, sceneX, sceneY, screenX, screenY, button, clickCount, shiftDown, controlDown, altDown, metaDown, primaryButtonDown, middleButtonDown, secondaryButtonDown, synthesized, popupTrigger, pickResult, gestureSource);
            this.fireEvent(touchPoint.getCurrentTargetNode(), mouseDragEvent);
        });
    }

    protected void fireMouseEvent(TuioTouchPoint touchPoint, EventType<MouseEvent> eventType, double sceneX, double sceneY, double screenX, double screenY, boolean primaryButtonDown, boolean secondaryButtonDown, boolean stillSincePress, int clickCount, MouseButton button, boolean dragDetected) {
        boolean synthesized = true;
        boolean shiftDown = false;
        boolean controlDown = false;
        boolean middleButtonDown = false;
        boolean metaDown = false;
        boolean popupTrigger = false;
        boolean altDown = false;
        Platform.runLater(() -> {
            PickResult pickResult = new PickResult(touchPoint.getTargetNode(), touchPoint.getSceneX(), touchPoint.getSceneY());
            MouseEvent mouseEvent = new MouseEvent(eventType, sceneX, sceneY, screenX, screenY, button, clickCount, shiftDown, controlDown, altDown, metaDown, primaryButtonDown, middleButtonDown, secondaryButtonDown, synthesized, popupTrigger, stillSincePress, pickResult);
            if (dragDetected && eventType == MouseEvent.MOUSE_DRAGGED) {
                MouseEvent detectedEvent = mouseEvent.copyFor(mouseEvent.getSource(), touchPoint.getTargetNode(), MouseEvent.DRAG_DETECTED);
                this.fireEvent(touchPoint.getTargetNode(), detectedEvent);
                mouseEvent.setDragDetect(dragDetected);
            }

            this.fireEvent(touchPoint.getTargetNode(), mouseEvent);
        });
    }

    protected void fireMouseEvent(TuioTouchPoint touchPoint, EventType<MouseEvent> eventType, boolean primaryButtonDown, boolean secondaryButtonDown, boolean stillSincePress, int clickCount, MouseButton button, boolean dragDetected) {
        double sceneX = touchPoint.getSceneX();
        double sceneY = touchPoint.getSceneY();
        double screenX = touchPoint.getScreenX();
        double screenY = touchPoint.getScreenY();
        this.fireMouseEvent(touchPoint, eventType, sceneX, sceneY, screenX, screenY, primaryButtonDown, secondaryButtonDown, stillSincePress, clickCount, button, dragDetected);
    }

    protected void fireMouseEvent(TuioTouchPoint touchPoint, EventType<MouseEvent> eventType, boolean primaryButtonDown, boolean secondaryButtonDown, boolean stillSincePress, int clickCount, MouseButton button) {
        boolean dragDetected = false;
        this.fireMouseEvent(touchPoint, eventType, primaryButtonDown, secondaryButtonDown, stillSincePress, clickCount, button, dragDetected);
    }

    protected Point2D getCentroid() {
        float sumX = 0.0F;
        float sumY = 0.0F;

        int i;
        for (i = 0; i < this.touchPointsCount; ++i) {
            if (i < this.maxNumberOfTouches) {
                sumX = (float) (sumX + this.touchPointsList.get(i).getSceneX());
                sumY = (float) (sumY + this.touchPointsList.get(i).getSceneY());
            }
        }

        i = Math.min(this.touchPointsCount, this.maxNumberOfTouches);
        float focusX = sumX / (float) i;
        float focusY = sumY / (float) i;
        return new Point2D(focusX, focusY);
    }

    protected boolean touchWithinMaxPoints(TuioTouchPoint touchPoint) {
        for (int i = 0; i < this.touchPointsCount && i <= this.maxNumberOfTouches - 1; ++i) {
            if (touchPoint.equals(this.touchPointsList.get(i))) {
                return true;
            }
        }

        return false;
    }

    public Point2D sceneXYToscreenYX(double sceneX, double sceneY) {
        double x;
        double y;
        if (this.config.isUseIndirectInputDevice()) {
            x = sceneX;
            y = sceneY;
        } else {
            Scene scene = this.getTargetNode().getScene();
            double windowX = scene.getWindow().getX();
            x = sceneX + windowX + scene.getX();
            double windowY = scene.getWindow().getY();
            y = sceneY + windowY + scene.getY();
        }

        return new Point2D(x, y);
    }

    public abstract void touchesBegan(TuioTouchPoint var1);

    public abstract void touchesMove(TuioTouchPoint var1);

    public abstract void touchesEnd(TuioTouchPoint var1);
}
